package org.wuyichun.eduserver.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.wuyichun.base.util.PageInfo;
import org.wuyichun.eduserver.domain.Department;
import org.wuyichun.eduserver.mapper.DepartmentMapper;
import org.wuyichun.eduserver.query.DepartmentQuery;
import org.wuyichun.eduserver.service.IDepartmentService;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
public class DepartmentServiceImpl implements IDepartmentService {
    @Autowired
    private DepartmentMapper mapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Transactional
    @Override
    public void insert(Department department) {

        redisTemplate.delete("departmentList");
        mapper.insert(department);
        // 处理dir_path
        // 判断 department.parentId 是否存在
        if (Objects.isNull(department.getParent().getId())){
            // 没有父级 路径就是自己的id
            department.setDirPath("/"+department.getId());
        }else{
            // 有父级先查父级 然后父级的路径+自己id
            Department parent = department.getParent();
            Department department1 = mapper.selectById(parent.getId());
            department.setDirPath(department1.getDirPath()+"/"+department.getId());
        }
        mapper.update(department);
        try {
            Thread.sleep(2000);
            redisTemplate.delete("departmentList");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Transactional
    @Override
    public void delete(Serializable id) {
        // 数据都在redis 那么就不会查数据库
        // 多线程
        // 请问 如果删除redis中的数据 是先删redis 还是先删数据库?
        // 如果先删数据库 a 删了数据库 但是 在删redis的时候网络波动 需要200ms
        //              b 删了数据库 并同步完了redis
        // 先删redis? 在删数据库?
        // a 删redis  在删数据库卡住
        // b 删redis  删完了数据库 同步
        redisTemplate.delete("departmentList");
        mapper.delete(id);
        try {
            Thread.sleep(2000);
            redisTemplate.delete("departmentList");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Transactional
    @Override
    public void update(Department department) {
        redisTemplate.delete("departmentList");
        // 处理dir_path
        if (Objects.isNull(department.getParent().getId())){
            department.setDirPath("/"+department.getId());
        }else{
            Department department1 = mapper.selectById(department.getParent().getId());
            department.setDirPath(department1.getDirPath()+"/"+department.getId());
        }
        mapper.update(department);
        try {
            Thread.sleep(2000);
            redisTemplate.delete("departmentList");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Department selectById(Serializable id) {
        return mapper.selectById(id);
    }

    @Override
    public List<Department> selectAll() {
        // 查全部以前 先看redis 有没有 有就直接从redis中获取
        Object list = redisTemplate.opsForValue().get("departmentList");
        if(Objects.isNull(list)){
            // 如果没有才查数据库
            List<Department> list1 = mapper.selectAll();
            // 存如redis
            redisTemplate.opsForValue().set("departmentList",list1);
            return list1;
        }
        return (List<Department>)list;
    }
    @Override
    public void batchDelete(List<Long> ids) {
        redisTemplate.delete("departmentList");
        mapper.batchDelete(ids);
    }

    @Override
    public PageInfo<Department> queryPage(DepartmentQuery departmentQuery) {
        // 高级查询和分页 只需要查 分页的数据 list = 10条 就OK了???  还要查total
        PageInfo<Department> pageInfo = new PageInfo<>();
        // 先查 total
        Long total = mapper.queryTotal(departmentQuery);
        if (total != 0){
            List<Department> list = mapper.queryPage(departmentQuery);
            pageInfo.setList(list);
            pageInfo.setTotal(total);
        }
        // 在查 list
        return pageInfo;
    }

    @Override
    public List<Department> getTree() {
        // 我们需要查询的是 一级树 包含 二级树  甚至包含三级树.... n级树
        // 我定义一个
        List<Department> listTree = new ArrayList<>();
        // 所有的部门都查询出来 all
        List<Department> all = mapper.selectAll();
        // 把查出来的 all 转成一个 map<id,Department>
        Map<Long, Department> map =
                all.stream().collect(Collectors.toMap(Department::getId, x -> x));
        // 遍历list
        for (Department department:all ) {
            // value判断 value.getParent 是不是null
            if (Objects.isNull(department.getParent())){
                // 如果 Parent 是null  那么就是加入 listTree
                listTree.add(department);
            } else{
                // 如果 Parent 不是null 我就获取他的   getChildren.add(value)
                map.get(department.getParent().getId()).getChildren().add(department);
            }
        }
        return listTree;
    }
}
